#ifndef DIGEST128_H
#define DIGEST128_H


#include <string>
#include <sstream>
#include <vector>
#include <assert.h>
#include "ultoa.h"


//________________________________________________________________________________________

//	t_digest



//		Holds the results of a 128 bit message hash


//________________________________________________________________________________________
template <int SIZE>
struct t_digest_N
{
	t_digest_N(unsigned* p)
				{
                    std::copy(p, p + SIZE, digest);
                }
	t_digest_N()
    {
        std::fill_n(digest, SIZE, 0U);
    }
	bool operator !=(const t_digest_N& o) const	{return ! (o == *this);}
	bool operator ==(const t_digest_N& o) const ;
	bool operator <(const t_digest_N& o) const ;
	unsigned trunc_to32() const{return digest[0];}
	std::string str(char i = '_') const;
	std::string single_field_str() const;
	unsigned digest[SIZE];
};

template <int SIZE>
inline bool t_digest_N<SIZE>::operator ==(const t_digest_N<SIZE>& o) const
	{	return std::equal(o.digest, o.digest+ SIZE, digest);	}

template <int SIZE>
inline bool t_digest_N<SIZE>::operator <(const t_digest_N<SIZE>& o) const
{
	return std::lexicographical_compare(o.digest, o.digest + SIZE, digest, digest + SIZE);
}

template <typename t_strm, int SIZE>
inline t_strm& operator << (t_strm& os, const t_digest_N<SIZE>& o)
{
	os << '['	<< o.digest[0];
    for (unsigned i = 1; i < SIZE; ++i)
        os     << ',' << o.digest[i];
    os << ']';
	return os;
}

template <int SIZE>
inline std::string t_digest_N<SIZE>::str(char c) const
{
	std::string ret;
    for (unsigned i = 0; i < SIZE - 1; ++i)
        ultoa(digest[i], ret) += c;
    ultoa(digest[SIZE - 1], ret);
	return ret;
}

template <int SIZE>
inline std::string& operator +=(std::string& ret, const t_digest_N<SIZE>& hash)
{
	ret						   += '{';
    ultoa(hash.digest[0], ret);
    for (unsigned i = 1; i < SIZE; ++i)
    {
        ret += ',';
        ultoa(hash.digest[i], ret);
    }
    ret += '}';
	return ret;
}


template <int SIZE>
inline std::string t_digest_N<SIZE>::single_field_str() const
{
	std::string ret;
	ret += (*this);
	return ret;
}



#endif

